//
//  ViewController.swift
//  Icon
//
//  Created by 1234 on 2023/1/31.
//

import Cocoa

class ViewController: NSViewController {
    
    private var data: Data?
    
    private lazy var openBtn: NSButton = {
        let button = NSButton()
        button.title = "选择图片(1024)"
        button.translatesAutoresizingMaskIntoConstraints = false
        button.action = #selector(openfile)
        
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0, constant: 100))
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40))
        
        return button
    }()
    
    private lazy var exportBtn: NSButton = {
        let button = NSButton()
        button.title = "导出xcode尺寸"
        button.translatesAutoresizingMaskIntoConstraints = false
        button.action = #selector(exportfile)
        
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0, constant: 100))
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40))
        
        return button
    }()
    
    private lazy var customSizeBtn: NSButton = {
        let button = NSButton()
        button.title = "自定义尺寸"
        button.translatesAutoresizingMaskIntoConstraints = false
        button.action = #selector(customSizeAction)
        
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0, constant: 100))
        button.addConstraint(NSLayoutConstraint.init(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40))
        
        return button
    }()
    
    private lazy var imgview: NSImageView = {
        let v = NSImageView()
        v.layer?.backgroundColor = NSColor.red.cgColor
        
        v.translatesAutoresizingMaskIntoConstraints = false
        v.addConstraint(NSLayoutConstraint.init(item: v, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0, constant: 200))
        v.addConstraint(NSLayoutConstraint.init(item: v, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 200))
        
        return v
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        initDefault()
        initSubviews()
        // Do any additional setup after loading the view.
        print(view.frame)
    }
    
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
    
    private func initDefault() {
        
    }
    private func initSubviews() {
        
        view.addSubview(openBtn)
        view.addSubview(exportBtn)
        view.addSubview(customSizeBtn)
        view.addSubview(imgview)
        
        view.addConstraint(NSLayoutConstraint.init(item: openBtn, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint.init(item: openBtn, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 0))
        
        view.addConstraint(NSLayoutConstraint.init(item: exportBtn, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint.init(item: exportBtn, attribute: .left, relatedBy: .equal, toItem: openBtn, attribute: .right, multiplier: 1, constant: 20))
        
        view.addConstraint(NSLayoutConstraint.init(item: customSizeBtn, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint.init(item: customSizeBtn, attribute: .left, relatedBy: .equal, toItem: exportBtn, attribute: .right, multiplier: 1, constant: 20))
        
        view.addConstraint(NSLayoutConstraint.init(item: imgview, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0))
        view.addConstraint(NSLayoutConstraint.init(item: imgview, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0))
        

        
        
    }
    
    //MARK: control action
    @objc private func openfile() {

        let panel = NSOpenPanel()
        panel.prompt = "选择"
        panel.directoryURL = nil
        panel.allowedFileTypes = ["png"]
        panel.beginSheetModal(for: self.view.window!) { [weak panel] resp in
            if (resp.rawValue != 0) {
                let d = try! Data(contentsOf: panel!.urls[0])
                let source = CGImageSourceCreateWithData(d as CFData, nil)
                let maskRef = CGImageSourceCreateImageAtIndex(source!, 0, nil)
                
                if (maskRef!.width != 1024 || maskRef!.height != 1024) {
                    self.showError("请选择像素宽高1024的图片")
                    return
                }
                self.data = d
                self.imgview.image = NSImage(data: d)
            }
        }
    }
    
    @objc private func exportfile() {
        if (data == nil) {
            showError("请选择图片")
            return
        }
        
        openSavePanpel("icons") {[weak self] path in
            self?.exportFile(path)
        }
    }
    
    @objc private func customSizeAction() {
        // 自定义尺寸
        if (data == nil) {
            showError("请选择图片")
            return
        }
        
        let tf = NSTextField(frame: NSRect(x: 0, y: 0, width: 200, height: 20))
        tf.placeholderString = "请输入自定义像素大小(整数)"
        
        let alert = NSAlert()
        alert.accessoryView = tf
        alert.messageText = "导出自定义尺寸"
        alert.addButton(withTitle: "确定")
        alert.addButton(withTitle: "取消")
//        alert.runModal()
        alert.beginSheetModal(for: view.window!) { resp in
            if resp == .alertFirstButtonReturn {
                // 确定
                guard let size = Double(tf.stringValue) else {
                    return
                }
                if size == 0 {
                    return
                }
                self.openSavePanpel("\(Int(size)).png") {[weak self] path in
//                    self?.exportFile(path)
                    self?.exportImages(size, name: path)
                }
                
            }
        }
    }
    
    private func exportFile(_ path: String) {
        if(!FileManager().fileExists(atPath: path)) {
            try! FileManager().createDirectory(atPath: path, withIntermediateDirectories: true)
        }
        let sizes: [String: CGFloat] = [
            "20@2x.png": 40,
            "20@3x.png": 60,
            "29@2x.png": 58,
            "29@3x.png": 87,
            "40@2x.png": 80,
            "40@3x.png": 120,
            "60@2x.png": 120,
            "60@3x.png": 180,
            "1024.png": 1024
        ]
        for (key, value) in sizes {
            exportImages(value, name: path + "/" + key)
        }

    }
    
    private func exportImages(_ size: CGFloat, name: String) {
        let screenScale = NSScreen.main?.backingScaleFactor ?? 1.0
        let targetSize = size / screenScale
        let targetRect = NSRect(x: 0, y: 0, width: targetSize, height: targetSize)
        
        let newImg = NSImage(size: targetRect.size)
        let img = NSImage(data: self.data!)!
        let rep = img.bestRepresentation(for: targetRect, context: nil, hints: nil)
        newImg.lockFocus()
        rep?.draw(in: targetRect)
        newImg.unlockFocus()
        
//        let d = newImg.tiffRepresentation(using: .lzw, factor: 0)
//        let bitmap = NSBitmapImageRep(data: d!)
//        let res_d = bitmap!.representation(using: .png, properties: [:])
//        try! res_d?.write(to: URL(fileURLWithPath:name), options: Data.WritingOptions.atomic)
        try! newImg.pngData(size: CGSize(width: size, height: size))?.write(to: URL(fileURLWithPath:name), options: Data.WritingOptions.atomic)
    }
    
    private func openSavePanpel(_ str: String, cb:@escaping ((String)->())) {
        let panel = NSSavePanel()
        panel.title = "保存图片"
        panel.nameFieldStringValue = str
        panel.message = "选择图片保存地址"
        panel.canCreateDirectories = true
        panel.beginSheetModal(for: view.window!) { resp in
            if (resp.rawValue == 1) {
                print(panel.url!.path)
                let p = panel.url!.path
                cb(p)
            }
        }
    }
    
    private func showError(_ msg: String = "错误") {
        let a = NSAlert()
        a.messageText = "提示"
        a.informativeText = msg
        a.addButton(withTitle: "确定")
        a.runModal()
    }
    
    
    
}

extension NSImage {
    func pngData(
        size: CGSize,
        imageInterpolation: NSImageInterpolation = .high
    ) -> Data? {
        guard let bitmap = NSBitmapImageRep(
            bitmapDataPlanes: nil,
            pixelsWide: Int(size.width),
            pixelsHigh: Int(size.height),
            bitsPerSample: 8,
            samplesPerPixel: 4,
            hasAlpha: true,
            isPlanar: false,
            colorSpaceName: .deviceRGB,
            bitmapFormat: [],
            bytesPerRow: 0,
            bitsPerPixel: 0
        ) else {
            return nil
        }

        bitmap.size = size
        NSGraphicsContext.saveGraphicsState()
        NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmap)
        NSGraphicsContext.current?.imageInterpolation = imageInterpolation
        draw(
            in: NSRect(origin: .zero, size: size),
            from: .zero,
            operation: .copy,
            fraction: 1.0
        )
        NSGraphicsContext.restoreGraphicsState()

        return bitmap.representation(using: .png, properties: [:])
    }
}

